IBM i のコード管理ツールとして
Gitを活用する
アプリケーションを複数のメンバーで開発する場合、メンバー間でソースコードの整合性をいかに保ち、管理するかが重要となる。そのための仕組みが、ソースコード管理である。ソースコード管理に利用するソフトウェアは、「バージョン管理ソフトウェア」と呼ばれる。
ILE RPGやCLといったIBM i 基幹アプリケーション・プログラムのソースコード管理には、以前からバージョン管理ソフトウェアとして「Rational Team Concert」(以下、RTC) が利用されてきた。しかし2016年にオープンソースのGitがIBM i のPASE上で提供され、IBM iユーザーもソースコード管理ツールとしてGitを使えるようになった。
Gitは、リーナス・トーバルスがLinuxカーネルの構成管理のために開発したツールで、分散型のバージョン管理ソフトウェアとして広く利用されている。バージョン管理ソフトウェアは、リポジトリーと呼ばれるソースの変更履歴情報を格納する領域を備えるが、リポジトリーの配置形態により、大きく「集中型」と「分散型」に分類される。
集中型バージョン管理ソフトウェアとは、図表1のようにバージョン管理サーバーにリポジトリーを配置し、各開発者はバージョン管理クライアントからそれぞれリポジトリーに接続する。集中型には、「Apache Subversion」(アパッチ・サブバージョン、SVN) などがある。RTCのソースコード管理機能も集中型である。
集中型の場合、各開発者は管理サーバーに接続しなければ、リポジトリー情報の取得や変更情報の登録を行えない。そのため、バージョン管理サーバーに常時接続した状態での開発が前提となる。
これに対して分散型バージョン管理ソフトウェアとは、図表2のように中央リポジトリーのほかに、各開発者の個人環境 (個人PC) 上にリポジトリーを配置する形態であり、Gitはこの分散型となる。中央リポジトリーだけでなく、各個人環境にリポジトリーが存在し、変更情報を保持するので、ネットワークに接続していない環境であっても、個人環境内でソースの変更管理などが行える。
また、各個人環境のリポジトリーに保持された情報を中央リポジトリーに反映したり、中央リポジトリー内の情報を各個人環境に取り込んだりすることで、開発メンバー間でソースや変更履歴情報の整合性を保持できる。
Gitでは中央のリポジトリーを「リモート・リポジトリー」、各個人環境のリポジトリーを「ローカル・リポジトリー」と呼ぶ。Gitを用いて開発する場合、最初にリモート・リポジトリーを開発者の個人環境に複製することで、ローカル・リポジトリーを作成する。この複製操作を「クローン 」(git clone)と呼ぶ。
開発者は自身のローカル・リポジトリーに、ソースの変更履歴情報を記録する。この記録作業を「コミット」(git commit)と呼ぶ。またコミットした変更履歴情報をほかの開発者と共有するには、リモート・リポジトリーに情報をアップロードする必要がある。このアップロード操作を「プッシュ」(git push) と呼ぶ。これとは逆に、リモート・リポジトリーにある情報を、開発者がローカル・リポジトリーにダウンロードする操作を「プル」(git pull) と呼ぶ。図表3に、これらの操作を示した。
IBM i のPASE環境でGitの利用が可能になり、IBM i のIFS上にリモート・リポジトリーを作成できるようになった。また、Part 2で解説したRDiやOrionはそれぞれGitとの連携機能を有するので、バージョン管理サーバーのような役割をIBM i に担わせつつ、GUIでIBM i 基幹アプリケーション・プログラムを開発できる。
図表4の環境を例にとりながら、以下に、RDiとOrionのそれぞれでGitを利用する方法を解説する。
ここには、DEVUSER01とDEVUSER02という2名の開発者がいる。DEVUSER01がRDiで、IBMI73_IMAGDEMOという名称のiプロジェクトによりコード開発している。そこにDEVUSER02が加わり、Orionを利用して、DEVUSER01に協力する形でコード開発することになった。
そこでIBM i のIFS上にリモート・リポジトリーを作成し、DEVUSER01のもつ既存iプロジェクトのソースをGitのバージョン管理下に入れ、リモート・リポジトリーにプッシュしたうえで、DEVUSER02がOrionからプルするという想定で手順を見ていく。
IBM i のIFS上に
リモート・リポジトリーを作成
Gitは2018年7月時点では、5733OPSのPTF SI63502としてGit 2.10.2が提供されている。このPTFを適用すれば、IBM i のPASE上でGitが使用できる。まずは、IBM i のIFS上にリモート・リポジトリーを作成することから始めよう。
Gitのリポジトリーには、「ベア・リポジトリー」と「ノンベア・リポジトリー」がある。
ノンベア・リポジトリーは、「ワーキング・ディレクトリ」(プログラム・ソースの実体ファイルを変更履歴情報と合わせて格納するディレクトリ)を内包する。これに対して、ベア・リポジトリーには実体ファイルはなく、あくまで変更履歴情報のみを格納する。通常、リモート・リポジトリーとしてはベア・リポジトリーを、ローカル・リポジトリーとしてはノンベア・リポジトリーを利用する。
今回、IBM i のIFS上に作成するリポジトリーはリモート・リポジトリーなので、形態としてはベア・リポジトリーを選択する。
まずCALL QP2TERMでPASE環境に入り、リポジトリーを作成したいディレクトリに移動する。そのあと、git init –bare –shared コマンドを実行すれば、ベア・リポジトリーが作成できる。
なおベア・リポジトリーのディレクトリ名称としては、.gitを接尾辞として付けることが通例となっているので、名称を決める際の参考にしよう。今回は、/gitrepos/imagdemo.gitというディレクトリにベア・リポジトリーを作成している(図表5)。
[図表5] IBM iのIFSにベア・リポジトリーを作成
RDi+EGitによる連携
RDiはPart 2で解説したように、Eclipseベースの統合開発環境であり、EclipseのGitプラグインであるEGitを利用できる。ここでは、RDiでEGitを用いた開発方法について述べる。
なお、IBM iのIFS上にGitリモート・リポジトリーを作成して利用する場合、文字コードはUTF-8 (CCSID 1208)となる。そのため、RDi側の文字コードもUTF-8にしておくとよい。RDi全体としての文字コードを変更する場合には、RDiのeclipse.iniで-Dfile.encoding=UTF-8を指定する。
EGitプラグイン使用時の環境設定
RDiでEGitプラグインを使用する場合の環境設定として、「ウインドウ」→「設定」→「チーム」→「Git」で適宜設定する。ここではリモート・リポジトリーからローカル・リポジトリーをクローン作成する際の作成先ディレクトリや(図表6)、コミット/プッシュする際のメール・アドレスやユーザー名(図表7)などを設定する。
[図表6] Gitの設定( リポジトリー作成先ディレクトリー)
[図表7] Gitの設定( メール・アドレス/ユーザー名)
今回はRDiのiプロジェクトを、Gitリポジトリーによるバージョン管理対象にすると想定する。その場合、各ソースメンバーの変更履歴がリポジトリーに記録される。
またIBM i のソースメンバーの各レコードには、先頭12桁に行番号および変更日が記録されている。この行番号情報がファイルに存在すると、プログラムコードとしての内容に変化がないにもかかわらず、行番号が変更になっただけで、EGitが「変更」と感知することになる。Orionから同じソースを参照/編集する場合には行番号は不要なので、iプロジェクトからソースメンバーを編集するときにだけ行番号を付けておき、iプロジェクト内のファイルとして保存する際には除去するのが望ましい。
そのための設定として、「ウインドウ」→「設定」→「iプロジェクト」で「ダウンロードでシーケンス番号と日付フィールドを除去する」および「シーケンス番号の追加と除去アクションを有効にする」にチェックを入れておく。
なおソース内の改行コードについても、IBM iのPASE上で稼働するGitとの連携を踏まえると、UNIX形式で統一しておくのがよいだろう。改行コードは、「ウインドウ」→「設定」→「一般」→「ワークスペース」の「新規テキスト・ファイルの行区切り文字」で指定できる。
RDi
既存iプロジェクトのソースを
Gitでバージョン管理する
ローカル・リポジトリーの作成
先ほど作成したIBM i 上のリモート・リポジトリーのクローンを、ローカル・リポジトリーとして作成しよう。
RDiのGitパースペクティブの「Gitリポジトリー」ビューにある「Gitリポジトリーのクローン作成」リンクをクリックする。「Gitリポジトリーのクローン作成」ウィザードが表示されるので、各項目を入力して、「次へ」をクリックする(図表8)。
[図表8] 「Gitリポジトリーのクローン作成」ウィザード
なお、ローカル・リポジトリーからIBM i のPASE上にあるリモート・リポジトリーへ接続するユーザー設定としては、(1)共通ユーザー・プロファイルを作成する、(2)ローカル・リポジトリー側のユーザーがもつSSH公開鍵を認証済み鍵として共通ユーザー・プロファイルに登録する、といった手順が一般的である。ただし今回はシンプルに、SSHでユーザー/パスワードを指定し、開発PCからIBM i に接続すると想定する。
「Gitリポジトリーのクローン作成」ウィザードの項目入力値は、以下のとおりである。
ホスト:IBM i のホスト名 (もしくはIPアドレス)
リポジトリー・パス:IBM i 上のリモート・リポジトリーのIFSディレクトリ
プロトコル:ssh
ユーザー/パスワード:SSH接続する際のIBM i ユーザー・プロファイル/パスワード
次に、「ブランチ選択」画面が表示される。リモート・リポジトリーは作成したばかりで何も入っていないので、空である旨のメッセージが表示されるが、設定した内容でリモート・リポジトリーに接続できていることは確認できる。そのまま「次へ」をクリックすると、「ローカル宛先」画面が表示される。
「ローカル宛先」画面ではクローン先のディレクトリを指定できるが、デフォルトでは環境設定にて指定したディレクトリが表示される。適切なディレクトリが指定されていることを確認して、「終了」をクリックする。
以上で、IBM i 上のリモート・リポジトリーからクローン作成したローカル・リポジトリーが作成できる。作成したリポジトリーは、「Gitリポジトリー」ビューに表示される(図表9)。ローカル・リポジトリーは作成できたものの、ソースはまだなく、リモート・リポジトリー上にもまだ何も登録されていない状態にある。次に、開発メンバー間の共有ベースとなるソースメンバーを、リモート・リポジトリーにアップロード (Gitではプッシュ) してみよう。
[図表9] 作成したローカル・リポジトリー
既存iプロジェクトを
ローカル・リポジトリーへ登録
まずRDiの既存iプロジェクトのソースを、ローカル・リポジトリーに登録する。iプロジェクト・パースペクティブを開き、「iプロジェクト」ビューにリストされているiプロジェクトを右クリック→「チーム」→「プロジェクトの共有」と選択すると、「プロジェクトの共有」ウィザードが起動する(図表10)。
[図表10] プロジェクトの共有
ウィザードでは最初に、共有するリポジトリー・タイプの選択が表示されるので、「Git」を選択し、「次へ」をクリックする。すると「Gitリポジトリーの構成」画面が表示されるので、リポジトリーとして作成したローカル・リポジトリーを選択する。そのあと、「終了」をクリックすれば完了である。
これまで、既存iプロジェクトの各ソースは個人PCのなかで、RDiのワークスペースとして指定されているディレクトリ配下にファイルとして格納されていた。しかしこの操作によって、ローカル・リポジトリーのディレクトリ配下に移され、Gitの検知下に置かれるようになる。
なおこの状態では、ローカル・リポジトリーには登録されているが、ローカル・リポジトリー内でまだコミットされておらず、リモート・リポジトリーにもプッシュされていない。
ローカル・リポジトリーでのコミットと
リモート・リポジトリーへのプッシュ
ここでは、複数メンバーによる開発のベースとなるプログラム・ソースを、まずローカル・リポジトリーでコミットし、それからリモート・リポジトリーへプッシュする。
コミットの前にまず、コミットしたいリソースのインデックス (索引) へ追加 (登録) する必要がある。インデックスは、開発者が編集を終えたソースのなかでコミットしたいものを登録する中間エリアと考えればよい。編集を終えたものの、インデックスに登録されていないファイルは、Gitパースペクティブの「Gitステージング」ビューにある「未ステージの変更」セクションにリストされる。
今回はベースとなるソースすべてを一度にコミットおよびプッシュしたいので、「未ステージの変更」にリストされているソースを一括でハイライト選択し、右クリック→「索引に追加」を選択する(図表11)。するとソースは「未ステージの変更」セクションから、「ステージ済みの変更」セクションに移る。
[図表11] ソースのインデックスへの登録
以上でインデックスへの登録が完了したので、次はローカル・リポジトリーでコミットし、同時にリモート・リポジトリーにプッシュする。コミットする際には、コミット・メッセージを入れる。メッセージはブランクフォームに自由形式で記入するが、後々の参照時や他の開発者でもわかりやすいように、コミットの理由や概要を入れて書くことがポイントである。
フォーマット例は、Webサイトに参考情報がある。なお今回は操作の紹介が目的なので、単純に最初のコミットであることを意味する「First Commit」と入れてコミットする。コミット・メッセージを記入後、「コミットしてプッシュ」をクリックする(図表12)。
[図表12] ソースのコミットとリモート・リポジトリーへのプッシュ
すると「ブランチmasterをプッシュ」ウィザードが起動するので、ウィザードに従って実行すれば、リモート・リポジトリーへのプッシュが完了する。
Orion
リモート・リポジトリーのクローンから
ローカル・リポジトリーを作成
では次に、DEVUSER02がOrionでリモート・リポジトリーのクローンを作成し、ローカル・リポジトリーを作成する手順を見ていこう。
Orionのワークスペース左端にあるGitのアイコンをクリックすると、OrionのGitビューが表示される。Gitビューの上部左側にある「Repositories▼」をクリック後、「Clone Repository」をクリックする。
リモート・リポジトリーのURL入力ウインドウが表示されるので、[プロトコル]://[ユーザー名]@[システム名]/[リモート・リポジトリー・ディレクトリー]の形式で入力し、「Submit」をクリックする(図表13)。途中でパスワードないしは認証鍵を入れるプロンプトが表示されるので、適宜入力する。
[図表13] リモート・リポジトリーの指定
クローンが完了すると、DEVUSER02のOrion Gitビューの「History」セクションにソースの履歴が表示され、そこからDEVUSER01が最初にコミットしたことなどが確認できる。
では、実際にソースが取り込めているかを確認しよう。Orionワークスペース左側にあるEditorアイコンをクリックし、Editorビューを開く。画面左側のコンテンツ・ツリーにDEVUSER01がプッシュした各ソース・ファイルおよびメンバーがあり、実際にソースを開いて編集できる(図表14)。
[図表14] OrionワークスペースのEditorビュー
このように、IBM i のIFS上にあるGitリモート・リポジトリーを介して、ソース変更履歴情報を簡単に共有できる。
RDi
ソースの編集とコミット
リモート・リポジトリーへのプッシュ
行番号の付加・削除
Gitリポジトリーで管理しているILE RPGのソース編集も、基本的には通常のRDiやOrionでのソース編集手順と変わらない。ただし、iプロジェクトは各行番号および日付が除去された形でソースを保持するので、通常のダブルクリックでソースメンバーを開くと、行番号のない状態でソースメンバーの編集画面が表示される。
行番号のない状態では、SEUの行コマンドは利用できない。行番号を付けた状態で編集したい場合には、図表15のように、「iプロジェクト」ビューの該当ソースメンバーを右クリック→「シーケンス番号と日付の追加」をクリックしたあとにダブルクリックで開く。すると図表16のように、行番号が付加された形で表示される。
[図表15] シーケンス番号と日付の追加
[図表16] 行番号が付加された状態でのソース編集画
なお行番号を付加してソースを編集した場合は、ソース編集画面を閉じたあとで、忘れずに「シーケンス番号と日付の除去」をクリックする。これにより、Gitリポジトリーへの変更情報登録に単純な行番号や日付の違いを含めずに済む。
ローカル・リポジトリーへのコミット
次にローカル・リポジトリーへコミットする。ローカル・リポジトリーにコミットされているソースからの未コミットの変更箇所があるソースには、「>」マークが自動で付記される。ソースの変更をローカル・リポジトリーにコミットするには既述のとおり、まずインデックス (索引) への追加が必要である。
追加はGitパースペクティブの「Gitステージング」ビューにリストされるソースを右クリック→「索引に追加」を選択する。あるいは「未ステージの変更」エリアから、該当ソースを「ステージ済みの変更」にドラッグ&ドロップで移動させてもよい。「ステージ済みの変更」にソースが移動されたことを確認後、コミット・メッセージを記入して「コミット」をクリックすると、コミットが完了である(図表17)。
[図表17] ローカル・リポジトリーへのコミット
リモート・リポジトリーへのプッシュ
ローカル・リポジトリーにコミットしただけでは、変更内容を他の開発者と共有できない。リモート・リポジトリーへのプッシュが必要となる。
プッシュはGitパースペクティブの「Gitリポジトリー」ビューで、ローカル・リポジトリーを右クリック→「ブランチ ‘xxxxxx’ をプッシュ」を選択する(図表18)。今回はmasterブランチを直接使用するので、「ブランチ ‘master’ をプッシュ」となる。
[図表18] コミットのリモート・リポジトリーへのプッシュ
Orion
リモート・リポジトリーからの取り込み
ソースの編集とコミット
DEVUSER01がRDiで編集したソースを、リモート・リポジトリーへプッシュしたので、ここではDEVUSER02がその変更内容をOrionで自分のローカル・リポジトリーに取り込む方法について説明する。
フェッチ
まず変更内容をリモート・リポジトリーから取得するために、Orion Gitビューの「Incoming」セクションにある「Fetch▼」をクリックし、「Fetch」を選択する(図表19) 。この取得を「フェッチ」 (git fetch) と呼ぶ。実行すると、DEVUSER01がプッシュしたコミットの内容が表示される。
[図表19] リモート・リポジトリーからのフェッチ
マージ
「Incoming」セクションに表示されたDEVUSER01のコミットは、まだDEVUSER02のローカル・リポジトリーに取り込まれていない状態にある。「Incoming」セクションにあるDEVUSER01によるコミットをクリックすると、このコミットによって変更された内容が画面右側に表示される。
リモート・リポジトリーから、フェッチしたコミットを自身のローカル・リポジトリーに取り込むことを「マージ」(git merge)と呼ぶ。「Incoming」セクションの (さくらんぼのような) マージ・アイコンをクリックすると、マージが完了する(図表20)。
[図表20] フェッチしたコミットのマージ
Editorビューに戻ってローカル・リポジトリーのソースを開くと、DEVUSER01のコミットが反映されていることがわかる。チームで開発する場合、開発者は最初にフェッチして、自身がローカルに取り込んでいないコミットがリモート・リポジトリーに出ていない状態にしてから開発を始めることが重要である。
ソースの編集とコミット
DEVUSER02は、DEVUSER01がリモート・リポジトリーにプッシュしたコミットを取り込んだ。ここからDEVUSER02はソースの編集作業を開始する。
Editorビューでソースを編集後にGitビューを表示すると、画面上部左側にワーキング・ディレクトリ内で変更されたファイルの存在が表示される。この「Working Directory Changes」をクリックすると、Gitビューの画面右側コンテンツ領域に変更内容が表示される(図表21)。
[図表21] Orionでのソースのローカル・リポジトリーへのコミット
コンテンツ領域上部に、コミット・メッセージの入力エリアと「Commit」ボタンがある。コミットしたい場合には、コミットに含めたい変更済みファイルのチェックボックスにチェックを入れたうえで(ここでチェックボックスにチェックを入れることが、RDiでのインデックスへの追加に相当する)、メッセージを入力し、「Commit」ボタンをクリックする。
クリックすると、「Ongoing」セクションにコミットがリストされる。これでコミットは完了である。
リモート・リポジトリーへのプッシュ
次に、コミットした内容をDEVUSER01と共有するために、リモート・リポジトリーへプッシュする。「Ongoing」セクションの「Push▼」をクリックし、「Push Branch」を選択する(図表22)。
[図表22] Orionでのリモート・リポジトリーへのプッシュ
なおプッシュが完了すると、「Ongoing」セクションに表示されていたコミットは「History」セクションに移動する。以上で、プッシュが完了となる。
RDi
リモート・リポジトリーから
ローカル・リポジトリーへの取り込み
最後に、リモート・リポジトリーにプッシュされたDEVUSER02によるコミットを、DEVUSER01がRDiでローカル・リポジトリーに取り込む手順を見ていこう。
Gitパースペクティブの「Gitリポジトリー」ビューでローカル・リポジトリーを右クリック→「アップストリームから取り出し」を選択する。すると、「取り出し結果」ウインドウが表示され、DEVUSER02がOrionからプッシュしたコミットをリモート・リポジトリーから取り出した (フェッチした) ことがわかる(図表23)。
[図表23] 「取り出し結果」ウインドウ
取り出したDEVUSER02によるコミットをローカル・リポジトリーにマージするために、「Gitリポジトリー」ビューでローカル・リポジトリーを右クリック→「マージ」を選択する。すると「’master’ (ブランチ名) のマージ」ウインドウが表示される。
ウインドウ内の「マージ」をクリックすれば、マージが完了する。今回マージの対象となったソースを右クリック→「表示」→「履歴」と選択すると、「履歴」ビューにそのソースのコミット履歴が表示される(図表24)。
[図表24] ソースの「履歴」
履歴にはDEVUSER01のローカルでのコミットだけでなく、DEVUSER02によるコミットも合わせて表示されることがわかる。以上で、リモート・リポジトリーからの取り込みが完了する。
*
RDiを利用して開発するDEVUSER01と、Orionを利用して開発するDEVUSER02が、Gitを利用してソースの変更履歴情報をやり取りしつつ、開発を進める手順について簡単に見てきた。CL、RPGといったプログラム言語であっても、十分にGitによるバージョン管理の恩恵に預かれることがわかるだろう。
なお、今回のDEVUSER01とDEVUSER02のケースはあくまでシンプルな例であって、masterブランチのみを利用し、競合については割愛している。しかしGitについては数多くの情報、テクニック、運用方法がWeb上で公開されているので意欲的に検索し、ぜひ参考にしてほしい。
著者|中村 陽一 氏
日本アイ・ビー・エム システムズ・エンジニアリング株式会社
アセット企画
アドバイザリーITスペシャリスト
[i Magazine 2018 Autumn(2018年8月)掲載]
・・・・・・・・
特集|IBM iのDevOpsアプローチ ◎目次
IBM iの基幹システム開発にも、これからはDevOpsアプローチが求められる
・・・・・・・・
・・・・・・・・
オープンソースのGitを利用して、ソースコードや変更履歴情報を共有する
・・・・・・・・
IBM iでJenkinsを使う、オープンソースベースの標準的なビルド管理を実現
[i Magazine 2018 Autumn(2018年8月)掲載]